/***************************************
* Normandes jose santos Jr     7656540 
* Jhonata Pereira Martins      7656637 
* Rafael Araujo de Oliveira    77049971
****************************************/





#include<stdlib.h>
#include<stdio.h>

#define CREATOR "grupo1"
#define RGB_COMPONENT_COLOR 255


typedef struct PPMImage
{
	int x,y;
	unsigned  char **R;
	unsigned  char **G;
	unsigned  char **B;


}PPMImage;




unsigned   char ** alocar(int linha, int coluna) // funcao para alocaeco dinamica 
{   unsigned   char **v;
	int i; 

	if ((v = ( unsigned   char**) malloc(linha*sizeof(char*))) ==  NULL) 
	{
		printf("\n\n ERROR - ALOCACAO MEMORIA ");
		system("pause");
		exit (1); 
	}   
	else
		for(i=0;i<linha;i++)
		{
			if ((v[i]= ( unsigned   char*) malloc(coluna*sizeof(char))) == NULL)
			{
				printf ("\n\n ERROR - ALOCACAO MEMORIA ");
				system("pause");
				exit(1);
			}
		} 

	return v;
}


// FILTRO DE GAUUS 

unsigned   char ** filtro(  unsigned char **v,int linha, int coluna)
{   unsigned char **saida = alocar(linha,coluna);


	int i,j,k,l,somatoria=0;

	for (i=0;i<linha ;i++)
	{ 
		for (j=0;j<coluna ;j++)
		{  somatoria=0;
			for (k=i-2;k<i+2 ;k++)
			{  
				for (l=j-2;l<j+2 ;l++)
				{  
					if( (k>0 ) && ( k<linha ) && (l>0)&& (l<coluna) )
						somatoria+= v[k][l];
					else
						somatoria += 0;                
				}         
			} 
			somatoria /= 25;
			saida[i][j] = somatoria;
		}  
	}  
	return saida ;
}
//CASO QUEIRA IMPRIMIR OS VALORES DAS MATRIZES DE  PIXEL
void imprimir(unsigned  char **v,int linha,int coluna)    
{
	int i,j;                    
	for (i=0;i<linha ;i++)
	{ 
		for (j=0;j<coluna ;j++)
		{  
			printf("%d\t",v[i][j]);
		}         
		printf("\n");
	}
	return;
}  






static PPMImage *readPPM(const char *filename)
{ int i,j; 
	char buff[16];
	PPMImage *img;
	FILE *fp;
	int c, rgb_comp_color;

	fp = fopen(filename, "rb");
	if (!fp) {
		fprintf(stderr, "Unable to open file '%s'\n", filename);
		exit(1);
	}


	if (!fgets(buff, sizeof(buff), fp)) {
		perror(filename);
		exit(1);
	}

	img = (PPMImage *)malloc(sizeof(PPMImage));
	if (!img) {
		fprintf(stderr, "Unable to allocate memory\n");
		exit(1);
	}


	c = getc(fp);
	while (c == '#') {
		while (getc(fp) != '\n') ;
		c = getc(fp);
	}

	ungetc(c, fp);

	if(fscanf(fp, "%d %d", &img->y, &img->x) != 2) 
	{
		fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
		exit(1);
	}


	if (fscanf(fp, "%d", &rgb_comp_color) != 1) {
		fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
		exit(1);
	}


	if (rgb_comp_color!= RGB_COMPONENT_COLOR) {
		fprintf(stderr, "'%s' does not have 8-bits components\n", filename);
		exit(1);
	}

	while (fgetc(fp) != '\n') ;
	//memory allocation for pixel data
	img->R = alocar(img->x,img->y);
	img->G = alocar(img->x,img->y);
	img->B = alocar(img->x,img->y);  


	if (!img) {
		fprintf(stderr, "Unable to allocate memory\n");
		exit(1);
	}


	do 
	{
		for (i=0;i<img->x ;i++)
		{ 
			for (j=0;j<img->y ;j++)
			{  
				fread(&img->R[i][j],sizeof(char),1,fp);
				fread(&img->G[i][j],sizeof(char),1,fp);
				fread(&img->B[i][j],sizeof(char),1,fp);                          

			}
		}
	} while (feof(fp) != 0 );
	fclose(fp);
	return img;
}



void writePPM(const char *filename, PPMImage *img)
{ int i,j;
	FILE *fp;
	//open file for output
	fp = fopen(filename, "wb");
	if (!fp) {
		fprintf(stderr, "Unable to open file '%s'\n", filename);
		exit(1);
	}

	//write the header file
	//image format
	fprintf(fp, "P6\n");

	//comments
	fprintf(fp, "# Created by %s\n",CREATOR);

	//image size
	//  fprintf(fp, "%d %d\n",img->x,img->y);
	fprintf(fp, "%d %d\n", img->y, img->x);

	// rgb component depth
	fprintf(fp, "%d\n",RGB_COMPONENT_COLOR);

	// pixel data

	// SAIDA DA NOVA IMAGEM

	for (i=0;i< img->x ;i++)
	{ 
		for (j=0;j<  img->y ;j++)
		{  

			fwrite(&img->R[i][j],sizeof(char),1,fp);      
			fwrite(&img->G[i][j],sizeof(char),1,fp);
			fwrite(&img->B[i][j],sizeof(char),1,fp);

		}

	}


	fclose(fp); 
}


int main(int argc , char*argv[])
{   PPMImage *imagem,
	saida ;

	imagem = readPPM(argv[1]);
	saida.x= imagem->x;
	saida.y= imagem->y;

	
	struct timeval utime;
	double tInicio;
	double tFim;
	int i;

	gettimeofday(&utime, NULL);

	tInicio = utime.tv_sec + ( utime.tv_usec / 1000000.0 );

	saida.R = filtro(imagem->R, imagem->x,imagem->y);
	saida.G = filtro(imagem->G, imagem->x,imagem->y);
	saida.B = filtro(imagem->B, imagem->x,imagem->y);



	gettimeofday(&utime, NULL);

	tFim = utime.tv_sec + ( utime.tv_usec / 1000000.0 );

	printf("%.4lf - Tempo percorrido\n", tFim - tInicio);

	writePPM("saida.ppm",imagem);
	writePPM("saida2.ppm",&saida);
	//   getchar();


	return 0;    
}     
